import { NotifyService } from '@farris/ui-notify';
import { RefreshFormService, ComponentResolveContext, ComponentBindingSourceContext, DomService } from '@farris/designer-services';
import { ControlContextMenuItem } from '../../../../../entity/control-context-menu';
import { ControlService } from '../../../../../service/control.service';
import { DgControl } from '../../../../../utils/dg-control';
import { FarrisDesignBaseComponent } from '@farris/designer-element';
import { ControlTreeNode } from '@farris/designer-devkit';
import { cloneDeep } from 'lodash-es';
import { DragResolveService } from '@farris/designer-devkit';
import { Injector } from '@angular/core';
import { RowNode } from '@farris/ui-treetable';
import { TabToolbarItemSchema } from '../../schema/schema';


export class TabChildContentContextMenuService {

    /** tab组件实例 */
    private cmpInstance: FarrisDesignBaseComponent;

    constructor(
        private notifyService: NotifyService,
        private controlService: ControlService,
        private refreshFormService: RefreshFormService,
        private domService: DomService,
        private injector: Injector,
        private parentRowNode: RowNode
    ) { }

    /**
     * 添加子级
     */
    addChildContent(cmpInstance: FarrisDesignBaseComponent, menuConfig: ControlContextMenuItem, rowNode: RowNode) {
        this.cmpInstance = cmpInstance;
        const parentTreeNode = this.parentRowNode && this.parentRowNode.node as ControlTreeNode;
        if (parentTreeNode && parentTreeNode.rawElement.type === DgControl.Tab.type) {
            this.childContentAddedToTabPage(menuConfig, rowNode);

        } else {
            this.childContentAddedToTab(menuConfig);
        }
    }

    /**
     * 右键选中Tab：支持添加空标签页、列表组件、附件上传预览组件（后两者默认添加到新标签页）
     * @param menuItem 右键配置
     */
    private childContentAddedToTab(menuItem: ControlContextMenuItem) {

        const rawTabDom = this.cmpInstance.component;

        switch (menuItem.id) {
            case DgControl.TabPage.type: {
                // 添加空标签页
                const newTabPage = this.createEmptyTabPage();
                rawTabDom.contents.push(newTabPage);

                this.refreshFormService.refreshFormDesigner.next(rawTabDom.id);
                break;
            }
            case DgControl.DataGrid.type: case DgControl.FileUploadPreview.type: {
                // 添加列表、附件
                const componentResolveContext = new ComponentResolveContext();
                componentResolveContext.controlType = menuItem.id;
                componentResolveContext.parentComponentInstance = { type: DgControl.Tab.type };
                componentResolveContext.needExcludeDisplayedEntity = menuItem.id === DgControl.FileUploadPreview.type;

                const dragResolveService = this.injector.get(DragResolveService);

                dragResolveService.triggerBindingEntity(componentResolveContext).subscribe(
                    (componentBindingSourceContext: ComponentBindingSourceContext) => {
                        if (!componentBindingSourceContext) {
                            return;
                        }
                        const componentRefParentElement = this.createEmptyTabPage();

                        if (componentBindingSourceContext.viewModelNode) {
                            componentRefParentElement.title = componentBindingSourceContext.viewModelNode.name;
                            const idPrefix = componentBindingSourceContext.viewModelNode.id.replace('-component-viewmodel', '');
                            componentRefParentElement.id = idPrefix + '-tab-page';
                            componentRefParentElement.toolbar.id = idPrefix + '-tab-toolbar';

                        }
                        rawTabDom.contents.push(componentRefParentElement);

                        this.insertComponent(componentBindingSourceContext, componentRefParentElement);

                        // 添加列表后，在tabpage上追加新增、删除按钮
                        if (menuItem.id === DgControl.DataGrid.type) {
                            componentResolveContext.bindingSourceContext = componentBindingSourceContext;
                            componentResolveContext.parentComponentInstance = { type: DgControl.TabPage.type };
                            dragResolveService.appendAddDeleteBtnToParentContainer(componentResolveContext, componentRefParentElement);
                        }

                        this.refreshFormService.refreshFormDesigner.next();
                    });

                break;
            }
            default: {
                this.notifyService.warning('暂不支持');
            }
        }
    }

    /**
     * 右键选中TabPage：支持添加列表组件、附件上传预览组件（在当前TabPage下添加）
     * @param menuItem 右键配置
     * @param rightMenuElement 控件树右键的控件节点
     */
    private childContentAddedToTabPage(menuItem: ControlContextMenuItem, rowNode: RowNode) {
        switch (menuItem.id) {
            case DgControl.DataGrid.type: case DgControl.FileUploadPreview.type: {
                // 添加列表、附件
                const componentRefParentElement = this.cmpInstance.component.contents.find(c => c.id === rowNode.id);
                if (this.checkComponentExisted(menuItem, componentRefParentElement)) {
                    this.notifyService.warning('【' + componentRefParentElement.title + '】内已存在' + menuItem.title + '控件，不能重复添加');
                    return;
                }
                const componentResolveContext = new ComponentResolveContext();
                componentResolveContext.controlType = menuItem.id;
                componentResolveContext.parentComponentInstance = { type: DgControl.Tab.type };
                componentResolveContext.needExcludeDisplayedEntity = menuItem.id === DgControl.FileUploadPreview.type;

                const dragResolveService = this.injector.get(DragResolveService);

                dragResolveService.triggerBindingEntity(componentResolveContext).subscribe(
                    (componentBindingSourceContext: ComponentBindingSourceContext) => {
                        if (componentBindingSourceContext) {
                            this.insertComponent(componentBindingSourceContext, componentRefParentElement);

                            // 添加列表后，在tabpage上追加新增、删除按钮
                            if (menuItem.id === DgControl.DataGrid.type) {
                                componentResolveContext.bindingSourceContext = componentBindingSourceContext;
                                componentResolveContext.parentComponentInstance = { type: DgControl.TabPage.type };
                                dragResolveService.appendAddDeleteBtnToParentContainer(componentResolveContext, componentRefParentElement);
                            }
                            this.refreshFormService.refreshFormDesigner.next();
                        }

                    });


                break;
            }
            default: {
                this.notifyService.warning('暂不支持');
            }
        }
    }

    /**
     * 右键创建空标签页
     */
    private createEmptyTabPage() {
        const tabPageMetadata = this.controlService.getControlMetaData(DgControl.TabPage.type);

        const randomNum = Math.random().toString(36).slice(2, 6);

        tabPageMetadata.id = 'tab-page-' + randomNum;
        tabPageMetadata.toolbar.id = 'tab-toolbar-' + randomNum;

        // const toolbarItem = cloneDeep(TabToolbarItemSchema);
        // toolbarItem.id = 'tab-toolbaritem-' + randomNum;
        // tabPageMetadata.toolbar.contents = [toolbarItem];

        return tabPageMetadata;
    }

    /**
     * 将组件相关节点插入DOM
     * @param componentBindingSourceContext 组件构造信息
     * @param componentRefParentNode 组件引用节点的父节点
     */
    private insertComponent(componentBindingSourceContext: ComponentBindingSourceContext, componentRefParentElement: any) {
        const { componentNode, componentRefNode, viewModelNode } = componentBindingSourceContext;
        this.domService.addComponent(componentNode);
        this.domService.addViewModel(viewModelNode);

        componentRefParentElement.contents.push(componentRefNode);
    }

    /**
     *  检查是否存在同类型的组件
     */
    private checkComponentExisted(menuItem: ControlContextMenuItem, componentRefParentElement: any) {

        for (const content of componentRefParentElement.contents) {
            if (content.type === DgControl.ComponentRef.type) {
                const comp = this.domService.getComponentById(content.component);
                if (comp && comp.componentType && comp.componentType.toLowerCase() === menuItem.id.toLowerCase()) {
                    return true;
                }
            }
        }


    }
}


